#ifndef EGS_ZONE_SERVER_MGR_H
#define EGS_ZONE_SERVER_MGR_H

//#include <nel/net/login_server.h>
#include <nel/net/unified_network.h>		//	for TServiceId
#include <nel/misc/singleton.h>
#include <nel/misc/sstring.h>
#include <game_share/utils.h>
#include <server_share/msg_struct_zone.h>
#include <server_share/server_def.h>
#include <game_share/scene_type.h>

namespace EGS
{

class CZoneServiceMgr : public NLMISC::CSingleton<CZoneServiceMgr>
{

public:

	void pushZoneService( MSG_STR::CZoneService& zs )
	{
		MSG_STR::CZoneService* pZoneService = findZoneService(zs.SId);
		if ( pZoneService != NULL )
		{
			getGlobal_Loger().displayNL( "register zone service is repeat. sid:%d", zs.SId.get() );
			removeZoneService(zs.SId);
		}
		_zs.push_back( zs );
	}

	MSG_STR::CZoneService* findZoneService( NLNET::TServiceId  con )
	{
		MSG_STR::CZoneService* zs = NULL;
		for( uint32 i=0; i<_zs.size(); i++ )
		{
			if( _zs[i].SId == con )
				zs = &_zs[i];
		}
		return zs;
	}

	NLNET::TServiceId findFreeScene( DEF::SCENE_ID scene_id )
	{
		uint min_used = -1;
		NLNET::TServiceId sid(NLNET::TServiceId::InvalidId);

		for( TZoneService::iterator iter = _zs.begin(); iter!=_zs.end(); iter++ )
		{
			for ( uint i=0; i<iter->SceneConfig.size(); ++i )
			{
				if ( iter->SceneConfig[i].SceneUsed < iter->SceneConfig[i].SceneMax )
				{
					if ( min_used > iter->SceneConfig[i].SceneUsed )
					{
						min_used = iter->SceneConfig[i].SceneUsed;
						sid      = iter->SId;
					}
				}
			}
		}

		return sid;
	}

	void removeZoneService( NLNET::TServiceId con )
	{
		for( TZoneService::iterator iter = _zs.begin(); iter!=_zs.end(); iter++ )
		{
			if( iter->SId == con )
			{
				_zs.erase( iter );
				break;
			}
		}
	}

	void report( NLMISC::CSString& cstr )
	{
		for ( uint i=0; i<_zs.size(); ++i )
		{
			cstr << "SID:" << _zs[i].SId << "\n";
			for ( uint j=0; j<_zs[i].SceneConfig.size(); ++j )
			{
				cstr << "SceneType:" << N_SCENE_TYPE::toString((DEF::E_SCENE_TYPE)(_zs[i].SceneConfig[j].SceneType));
				cstr << " SceneMax:" << _zs[i].SceneConfig[j].SceneMax;
				cstr << " SceneUsed:" << _zs[i].SceneConfig[j].SceneUsed;
			}
		}
	}

	CZoneServiceMgr()
	{
	}

private:

	typedef std::vector<MSG_STR::CZoneService>	TZoneService;
	TZoneService  _zs;
};

#define  ZoneServiceMgr  CZoneServiceMgr::instance()

}

#endif









